//所以我们可以编写一系列的isType 函数。代码如下：
var isString = function( obj ){
    return Object.prototype.toString.call( obj ) === '[object String]';
};
var isArray = function( obj ){
    return Object.prototype.toString.call( obj ) === '[object Array]';
};
var isNumber = function( obj ){
    return Object.prototype.toString.call( obj ) === '[object Number]';
};

var isType = function( type ){
    return function( obj ){
        return Object.prototype.toString.call( obj ) === '[object '+ type +']';
    }
};

var isString = isType( 'String' );
var isArray = isType( 'Array' );
var isNumber = isType( 'Number' );

console.log( isArray( [ 1, 2, 3 ] ) ); // 输出：true

//我们还可以用循环语句，来批量注册这些isType 函数：
var Type = {};
for ( var i = 0, type; type = [ 'String', 'Array', 'Number' ][ i++ ]; ){
    console.log('运行了', type );
    (function( type ){
        Type[ 'is' + type ] = function( obj ){
            return Object.prototype.toString.call( obj ) === '[object '+ type +']';
        }
    })( type )
};

Type.isArray( [] ); // 输出：true
Type.isString( "str" ); // 输出：true



var getSingle = function ( fn ) {
    var ret;
    return function () {
        return ret || ( ret = fn.apply( this, arguments ) );
    };
};

//这个高阶函数的例子，既把函数当作参数传递，又让函数执行后返回了另外一个函数。我们
//可以看看getSingle 函数的效果：

var getScript = getSingle(function(){
    return document.createElement( 'script' );
});
var script1 = getScript();
var script2 = getScript();
alert ( script1 === script2 ); // 输出：true